home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / dev / gg / ncurses-5.3.lha / ncurses-5.3 / c++ / cursesf.h < prev    next >
C/C++ Source or Header  |  2002-10-24  |  25KB  |  826 lines

  1. // * This makes emacs happy -*-Mode: C++;-*-
  2. /****************************************************************************
  3.  * Copyright (c) 1998,1999,2000,2001 Free Software Foundation, Inc.         *
  4.  *                                                                          *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a  *
  6.  * copy of this software and associated documentation files (the            *
  7.  * "Software"), to deal in the Software without restriction, including      *
  8.  * without limitation the rights to use, copy, modify, merge, publish,      *
  9.  * distribute, distribute with modifications, sublicense, and/or sell       *
  10.  * copies of the Software, and to permit persons to whom the Software is    *
  11.  * furnished to do so, subject to the following conditions:                 *
  12.  *                                                                          *
  13.  * The above copyright notice and this permission notice shall be included  *
  14.  * in all copies or substantial portions of the Software.                   *
  15.  *                                                                          *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
  18.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
  19.  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
  20.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
  21.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
  22.  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
  23.  *                                                                          *
  24.  * Except as contained in this notice, the name(s) of the above copyright   *
  25.  * holders shall not be used in advertising or otherwise to promote the     *
  26.  * sale, use or other dealings in this Software without prior written       *
  27.  * authorization.                                                           *
  28.  ****************************************************************************/
  29.  
  30. /****************************************************************************
  31.  *   Author: Juergen Pfeifer, 1997                                          *
  32.  *   Contact: http://www.familiepfeifer.de/Contact.aspx?Lang=en             *
  33.  ****************************************************************************/
  34.  
  35. // $Id: cursesf.h,v 1.17 2002/07/06 15:47:52 juergen Exp $
  36.  
  37. #ifndef NCURSES_CURSESF_H_incl
  38. #define NCURSES_CURSESF_H_incl 1
  39.  
  40. #include <cursesp.h>
  41. #include <string.h>
  42.  
  43. extern "C" {
  44. #  include <form.h>
  45. }
  46. //
  47. // -------------------------------------------------------------------------
  48. // The abstract base class for buitin and user defined Fieldtypes.
  49. // -------------------------------------------------------------------------
  50. //
  51. class NCURSES_IMPEXP NCursesFormField; // forward declaration
  52.  
  53. // Class to represent builtin field types as well as C++ written new
  54. // fieldtypes (see classes UserDefineFieldType...
  55. class NCURSES_IMPEXP NCursesFieldType {
  56.   friend class NCursesFormField;
  57.  
  58. protected:
  59.   FIELDTYPE* fieldtype;
  60.  
  61.   inline void OnError(int err) const THROWS(NCursesFormException) {
  62.     if (err!=E_OK)
  63.       THROW(new NCursesFormException (err));
  64.   }
  65.  
  66.   NCursesFieldType(FIELDTYPE *f) : fieldtype(f) {
  67.   }
  68.  
  69.   virtual ~NCursesFieldType() {}
  70.  
  71.   // Set the fields f fieldtype to this one.
  72.   virtual void set(NCursesFormField& f) = 0;
  73.  
  74. public:
  75.   NCursesFieldType() : fieldtype((FIELDTYPE*)0) {
  76.   }
  77. };
  78.  
  79. //
  80. // -------------------------------------------------------------------------
  81. // The class representing a forms field, wrapping the lowlevel FIELD struct
  82. // -------------------------------------------------------------------------
  83. //
  84. class NCURSES_IMPEXP NCursesFormField {
  85.   friend class NCursesForm;
  86.  
  87. protected:
  88.   FIELD *field;              // lowlevel structure
  89.   NCursesFieldType* ftype;   // Associated field type
  90.  
  91.   // Error handler
  92.   inline void OnError (int err) const THROWS(NCursesFormException) {
  93.     if (err != E_OK)
  94.       THROW(new NCursesFormException (err));
  95.   }
  96.  
  97. public:
  98.   // Create a 'Null' field. Can be used to delimit a field list
  99.   NCursesFormField()
  100.     : field((FIELD*)0), ftype((NCursesFieldType*)0) {
  101.   }
  102.  
  103.   // Create a new field
  104.   NCursesFormField (int rows,
  105.             int cols,
  106.             int first_row = 0,
  107.             int first_col = 0,
  108.             int offscreen_rows = 0,
  109.             int additional_buffers = 0)
  110.     : ftype((NCursesFieldType*)0) {
  111.       field = ::new_field(rows,cols,first_row,first_col,
  112.               offscreen_rows, additional_buffers);
  113.       if (!field)
  114.     OnError(errno);
  115.   }
  116.  
  117.   virtual ~NCursesFormField ();
  118.  
  119.   // Duplicate the field at a new position
  120.   inline NCursesFormField* dup(int first_row, int first_col) {
  121.     NCursesFormField* f = new NCursesFormField();
  122.     if (!f)
  123.       OnError(E_SYSTEM_ERROR);
  124.     else {
  125.       f->ftype = ftype;
  126.       f->field = ::dup_field(field,first_row,first_col);
  127.       if (!f->field)
  128.     OnError(errno);
  129.     }
  130.     return f;
  131.   }
  132.  
  133.   // Link the field to a new location
  134.   inline NCursesFormField* link(int first_row, int first_col) {
  135.     NCursesFormField* f = new NCursesFormField();
  136.     if (!f)
  137.       OnError(E_SYSTEM_ERROR);
  138.     else {
  139.       f->ftype = ftype;
  140.       f->field = ::link_field(field,first_row,first_col);
  141.       if (!f->field)
  142.     OnError(errno);
  143.     }
  144.     return f;
  145.   }
  146.  
  147.   // Get the lowlevel field representation
  148.   inline FIELD* get_field() const {
  149.     return field;
  150.   }
  151.  
  152.   // Retrieve info about the field
  153.   inline void info(int& rows, int& cols,
  154.            int& first_row, int& first_col,
  155.            int& offscreen_rows, int& additional_buffers) const {
  156.     OnError(::field_info(field, &rows, &cols,
  157.              &first_row, &first_col,
  158.              &offscreen_rows, &additional_buffers));
  159.   }
  160.  
  161.   // Retrieve info about the fields dynamic properties.
  162.   inline void dynamic_info(int& dynamic_rows, int& dynamic_cols,
  163.                int& max_growth) const {
  164.     OnError(::dynamic_field_info(field, &dynamic_rows, &dynamic_cols,
  165.                  &max_growth));
  166.   }
  167.  
  168.   // For a dynamic field you may set the maximum growth limit.
  169.   // A zero means unlimited growth.
  170.   inline void set_maximum_growth(int growth = 0) {
  171.     OnError(::set_max_field(field,growth));
  172.   }
  173.  
  174.   // Move the field to a new position
  175.   inline void move(int row, int col) {
  176.     OnError(::move_field(field,row,col));
  177.   }
  178.  
  179.   // Mark the field to start a new page
  180.   inline void new_page(bool pageFlag = FALSE) {
  181.     OnError(::set_new_page(field,pageFlag));
  182.   }
  183.  
  184.   // Retrieve whether or not the field starts a new page.
  185.   inline bool is_new_page() const {
  186.     return ::new_page(field);
  187.   }
  188.  
  189.   // Set the justification for the field
  190.   inline void set_justification(int just) {
  191.     OnError(::set_field_just(field,just));
  192.   }
  193.  
  194.   // Retrieve the fields justification
  195.   inline int justification() const {
  196.     return ::field_just(field);
  197.   }
  198.   // Set the foreground attribute for the field
  199.   inline void set_foreground(chtype fore) {
  200.     OnError(::set_field_fore(field,fore));
  201.   }
  202.  
  203.   // Retrieve the fields foreground attribute
  204.   inline chtype fore() const {
  205.     return ::field_fore(field);
  206.   }
  207.  
  208.   // Set the background attribute for the field
  209.   inline void set_background(chtype back) {
  210.     OnError(::set_field_back(field,back));
  211.   }
  212.  
  213.   // Retrieve the fields background attribute
  214.   inline chtype back() const {
  215.     return ::field_back(field);
  216.   }
  217.  
  218.   // Set the padding character for the field
  219.   inline void set_pad_character(int pad) {
  220.     OnError(::set_field_pad(field,pad));
  221.   }
  222.  
  223.   // Retrieve the fields padding character
  224.   inline int pad() const {
  225.     return ::field_pad(field);
  226.   }
  227.  
  228.   // Switch on the fields options
  229.   inline void options_on (Field_Options options) {
  230.     OnError (::field_opts_on (field, options));
  231.   }
  232.  
  233.   // Switch off the fields options
  234.   inline void options_off (Field_Options options) {
  235.     OnError (::field_opts_off (field, options));
  236.   }
  237.  
  238.   // Retrieve the fields options
  239.   inline Field_Options options () const {
  240.     return ::field_opts (field);
  241.   }
  242.  
  243.   // Set the fields options
  244.   inline void set_options (Field_Options options) {
  245.     OnError (::set_field_opts (field, options));
  246.   }
  247.  
  248.   // Mark the field as changed
  249.   inline void set_changed(bool changeFlag = TRUE) {
  250.     OnError(::set_field_status(field,changeFlag));
  251.   }
  252.  
  253.   // Test whether or not the field is marked as changed
  254.   inline bool changed() const {
  255.     return ::field_status(field);
  256.   }
  257.  
  258.   // Return the index of the field in the field array of a form
  259.   // or -1 if the field is not associated to a form
  260.   inline int (index)() const {
  261.     return ::field_index(field);
  262.   }
  263.  
  264.   // Store a value in a fields buffer. The default buffer is nr. 0
  265.   inline void set_value(const char *val, int buffer = 0) {
  266.     OnError(::set_field_buffer(field,buffer,val));
  267.   }
  268.  
  269.   // Retrieve the value of a fields buffer. The default buffer is nr. 0
  270.   inline char* value(int buffer = 0) const {
  271.     return ::field_buffer(field,buffer);
  272.   }
  273.  
  274.   // Set the validation type of the field.
  275.   inline void set_fieldtype(NCursesFieldType& f) {
  276.     ftype = &f;
  277.     f.set(*this); // A good friend may do that...
  278.   }
  279.  
  280.   // Retrieve the validation type of the field.
  281.   inline NCursesFieldType* fieldtype() const {
  282.     return ftype;
  283.   }
  284.  
  285. };
  286.  
  287. //
  288. // -------------------------------------------------------------------------
  289. // The class representing a form, wrapping the lowlevel FORM struct
  290. // -------------------------------------------------------------------------
  291. //
  292. class NCURSES_IMPEXP NCursesForm : public NCursesPanel {
  293. protected:
  294.   FORM* form;  // the lowlevel structure
  295.  
  296. private:
  297.   NCursesWindow* sub;   // the subwindow object
  298.   bool b_sub_owner;     // is this our own subwindow?
  299.   bool b_framed;        // has the form a border?
  300.   bool b_autoDelete;    // Delete fields when deleting form?
  301.  
  302.   NCursesFormField** my_fields; // The array of fields for this form
  303.  
  304.   // This structure is used for the form's user data field to link the
  305.   // FORM* to the C++ object and to provide extra space for a user pointer.
  306.   typedef struct {
  307.     void*              m_user;      // the pointer for the user's data
  308.     const NCursesForm* m_back;      // backward pointer to C++ object
  309.     const FORM*        m_owner;
  310.   } UserHook;
  311.  
  312.   // Get the backward pointer to the C++ object from a FORM
  313.   static inline NCursesForm* getHook(const FORM *f) {
  314.     UserHook* hook = (UserHook*)::form_userptr(f);
  315.     assert(hook != 0 && hook->m_owner==f);
  316.     return (NCursesForm*)(hook->m_back);
  317.   }
  318.  
  319.   // This are the built-in hook functions in this C++ binding. In C++ we use
  320.   // virtual member functions (see below On_..._Init and On_..._Termination)
  321.   // to provide this functionality in an object oriented manner.
  322.   static void frm_init(FORM *);
  323.   static void frm_term(FORM *);
  324.   static void fld_init(FORM *);
  325.   static void fld_term(FORM *);
  326.  
  327.   // Calculate FIELD* array for the menu
  328.   FIELD** mapFields(NCursesFormField* nfields[]);
  329.  
  330. protected:
  331.   // internal routines
  332.   inline void set_user(void *user) {
  333.     UserHook* uptr = (UserHook*)::form_userptr (form);
  334.     assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form);
  335.     uptr->m_user = user;
  336.   }
  337.  
  338.   inline void *get_user() {
  339.     UserHook* uptr = (UserHook*)::form_userptr (form);
  340.     assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form);
  341.     return uptr->m_user;
  342.   }
  343.  
  344.   void InitForm (NCursesFormField* Fields[],
  345.          bool with_frame,
  346.          bool autoDeleteFields);
  347.  
  348.   inline void OnError (int err) const THROWS(NCursesFormException) {
  349.     if (err != E_OK)
  350.       THROW(new NCursesFormException (err));
  351.   }
  352.  
  353.   // this wraps the form_driver call.
  354.   virtual int driver (int c) ;
  355.  
  356.   // 'Internal' constructor, builds an object without association to a
  357.   // field array.
  358.   NCursesForm( int  lines,
  359.            int  cols,
  360.            int  begin_y = 0,
  361.            int  begin_x = 0)
  362.     : NCursesPanel(lines,cols,begin_y,begin_x),
  363.       form ((FORM*)0) {
  364.   }
  365.  
  366. public:
  367.   // Create form for the default panel.
  368.   NCursesForm (NCursesFormField* Fields[],
  369.            bool with_frame=FALSE,         // reserve space for a frame?
  370.            bool autoDelete_Fields=FALSE)  // do automatic cleanup?
  371.     : NCursesPanel() {
  372.     InitForm(Fields, with_frame, autoDelete_Fields);
  373.   }
  374.  
  375.   // Create a form in a panel with the given position and size.
  376.   NCursesForm (NCursesFormField* Fields[],
  377.            int  lines,
  378.            int  cols,
  379.            int  begin_y,
  380.            int  begin_x,
  381.            bool with_frame=FALSE,        // reserve space for a frame?
  382.            bool autoDelete_Fields=FALSE) // do automatic cleanup?
  383.     : NCursesPanel(lines, cols, begin_y, begin_x) {
  384.       InitForm(Fields, with_frame, autoDelete_Fields);
  385.   }
  386.  
  387.   virtual ~NCursesForm();
  388.  
  389.   // Set the default attributes for the form
  390.   virtual void setDefaultAttributes();
  391.  
  392.   // Retrieve current field of the form.
  393.   inline NCursesFormField* current_field() const {
  394.     return my_fields[::field_index(::current_field(form))];
  395.   }
  396.  
  397.   // Set the forms subwindow
  398.   void setSubWindow(NCursesWindow& sub);
  399.  
  400.   // Set these fields for the form
  401.   inline void setFields(NCursesFormField* Fields[]) {
  402.     OnError(::set_form_fields(form,mapFields(Fields)));
  403.   }
  404.  
  405.   // Remove the form from the screen
  406.   inline void unpost (void) {
  407.     OnError (::unpost_form (form));
  408.   }
  409.  
  410.   // Post the form to the screen if flag is true, unpost it otherwise
  411.   inline void post(bool flag = TRUE) {
  412.     OnError (flag ? ::post_form(form) : ::unpost_form (form));
  413.   }
  414.  
  415.   // Decorations
  416.   inline void frame(const char *title=NULL, const char* btitle=NULL) {
  417.     if (b_framed)
  418.       NCursesPanel::frame(title,btitle);
  419.     else
  420.       OnError(E_SYSTEM_ERROR);
  421.   }
  422.  
  423.   inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
  424.     if (b_framed)
  425.       NCursesPanel::boldframe(title,btitle);
  426.     else
  427.       OnError(E_SYSTEM_ERROR);
  428.   }
  429.  
  430.   inline void label(const char *topLabel, const char *bottomLabel) {
  431.     if (b_framed)
  432.       NCursesPanel::label(topLabel,bottomLabel);
  433.     else
  434.       OnError(E_SYSTEM_ERROR);
  435.   }
  436.  
  437.   // -----
  438.   // Hooks
  439.   // -----
  440.  
  441.   // Called after the form gets repositioned in its window.
  442.   // This is especially true if the form is posted.
  443.   virtual void On_Form_Init();
  444.  
  445.   // Called before the form gets repositioned in its window.
  446.   // This is especially true if the form is unposted.
  447.   virtual void On_Form_Termination();
  448.  
  449.   // Called after the field became the current field
  450.   virtual void On_Field_Init(NCursesFormField& field);
  451.  
  452.   // Called before this field is left as current field.
  453.   virtual void On_Field_Termination(NCursesFormField& field);
  454.  
  455.   // Calculate required window size for the form.
  456.   void scale(int& rows, int& cols) const {
  457.     OnError(::scale_form(form,&rows,&cols));
  458.   }
  459.  
  460.   // Retrieve number of fields in the form.
  461.   int count() const {
  462.     return ::field_count(form);
  463.   }
  464.  
  465.   // Make the page the current page of the form.
  466.   void set_page(int page) {
  467.     OnError(::set_form_page(form,page));
  468.   }
  469.  
  470.   // Retrieve current page number
  471.   int page() const {
  472.     return ::form_page(form);
  473.   }
  474.  
  475.   // Switch on the forms options
  476.   inline void options_on (Form_Options options) {
  477.     OnError (::form_opts_on (form, options));
  478.   }
  479.  
  480.   // Switch off the forms options
  481.   inline void options_off (Form_Options options) {
  482.     OnError (::form_opts_off (form, options));
  483.   }
  484.  
  485.   // Retrieve the forms options
  486.   inline Form_Options options () const {
  487.     return ::form_opts (form);
  488.   }
  489.  
  490.   // Set the forms options
  491.   inline void set_options (Form_Options options) {
  492.     OnError (::set_form_opts (form, options));
  493.   }
  494.  
  495.   // Are there more data in the current field after the data shown
  496.   inline bool data_ahead() const {
  497.     return ::data_ahead(form);
  498.   }
  499.  
  500.   // Are there more data in the current field before the data shown
  501.   inline bool data_behind() const {
  502.     return ::data_behind(form);
  503.   }
  504.  
  505.   // Position the cursor to the current field
  506.   inline void position_cursor () {
  507.     OnError (::pos_form_cursor (form));
  508.   }
  509.   // Set the current field
  510.   inline void set_current(NCursesFormField& F) {
  511.     OnError (::set_current_field(form, F.field));
  512.   }
  513.  
  514.   // Provide a default key virtualization. Translate the keyboard
  515.   // code c into a form request code.
  516.   // The default implementation provides a hopefully straightforward
  517.   // mapping for the most common keystrokes and form requests.
  518.   virtual int virtualize(int c);
  519.  
  520.   // Operators
  521.   inline NCursesFormField* operator[](int i) const {
  522.     if ( (i < 0) || (i >= ::field_count (form)) )
  523.       OnError (E_BAD_ARGUMENT);
  524.     return my_fields[i];
  525.   }
  526.  
  527.   // Perform the menu's operation
  528.   // Return the field where you left the form.
  529.   virtual NCursesFormField* operator()(void);
  530.  
  531.   // Exception handlers. The default is a Beep.
  532.   virtual void On_Request_Denied(int c) const;
  533.   virtual void On_Invalid_Field(int c) const;
  534.   virtual void On_Unknown_Command(int c) const;
  535.  
  536. };
  537.  
  538. //
  539. // -------------------------------------------------------------------------
  540. // This is the typical C++ typesafe way to allow to attach
  541. // user data to a field of a form. Its assumed that the user
  542. // data belongs to some class T. Use T as template argument
  543. // to create a UserField.
  544. // -------------------------------------------------------------------------
  545. template<class T> class NCURSES_IMPEXP NCursesUserField : public NCursesFormField
  546. {
  547. public:
  548.   NCursesUserField (int rows,
  549.             int cols,
  550.             int first_row = 0,
  551.             int first_col = 0,
  552.             const T* p_UserData = (T*)0,
  553.             int offscreen_rows = 0,
  554.             int additional_buffers = 0)
  555.     : NCursesFormField (rows, cols,
  556.             first_row, first_col,
  557.             offscreen_rows, additional_buffers) {
  558.       if (field)
  559.     OnError(::set_field_userptr(field,(void *)p_UserData));
  560.   }
  561.  
  562.   virtual ~NCursesUserField() {};
  563.  
  564.   inline const T* UserData (void) const {
  565.     return (const T*)::field_userptr (field);
  566.   }
  567.  
  568.   inline virtual void setUserData(const T* p_UserData) {
  569.     if (field)
  570.       OnError (::set_field_userptr (field, (void *)p_UserData));
  571.   }
  572. };
  573. //
  574. // -------------------------------------------------------------------------
  575. // The same mechanism is used to attach user data to a form
  576. // -------------------------------------------------------------------------
  577. //
  578. template<class T> class NCURSES_IMPEXP NCursesUserForm : public NCursesForm
  579. {
  580. protected:
  581.   // 'Internal' constructor, builds an object without association to a
  582.   // field array.
  583.   NCursesUserForm( int  lines,
  584.            int  cols,
  585.            int  begin_y = 0,
  586.            int  begin_x = 0,
  587.            const T* p_UserData = (T*)0)
  588.     : NCursesForm(lines,cols,begin_y,begin_x) {
  589.       if (form)
  590.     set_user ((void *)p_UserData);
  591.   }
  592.  
  593. public:
  594.   NCursesUserForm (NCursesFormField Fields[],
  595.            bool with_frame=FALSE,
  596.            bool autoDelete_Fields=FALSE)
  597.     : NCursesForm (Fields, with_frame, autoDelete_Fields) {
  598.   };
  599.  
  600.   NCursesUserForm (NCursesFormField Fields[],
  601.            const T* p_UserData = (T*)0,
  602.            bool with_frame=FALSE,
  603.            bool autoDelete_Fields=FALSE)
  604.     : NCursesForm (Fields, with_frame, autoDelete_Fields) {
  605.       if (form)
  606.     set_user ((void *)p_UserData);
  607.   };
  608.  
  609.   NCursesUserForm (NCursesFormField Fields[],
  610.            int lines,
  611.            int cols,
  612.            int begin_y = 0,
  613.            int begin_x = 0,
  614.            const T* p_UserData = (T*)0,
  615.            bool with_frame=FALSE,
  616.            bool autoDelete_Fields=FALSE)
  617.     : NCursesForm (Fields, lines, cols, begin_y, begin_x,
  618.            with_frame, autoDelete_Fields) {
  619.       if (form)
  620.     set_user ((void *)p_UserData);
  621.   };
  622.  
  623.   virtual ~NCursesUserForm() {
  624.   };
  625.  
  626.   inline T* UserData (void) const {
  627.     return (T*)get_user ();
  628.   };
  629.  
  630.   inline virtual void setUserData (const T* p_UserData) {
  631.     if (form)
  632.       set_user ((void *)p_UserData);
  633.   }
  634.  
  635. };
  636. //
  637. // -------------------------------------------------------------------------
  638. // Builtin Fieldtypes
  639. // -------------------------------------------------------------------------
  640. //
  641. class NCURSES_IMPEXP Alpha_Field : public NCursesFieldType {
  642. private:
  643.   int min_field_width;
  644.  
  645.   void set(NCursesFormField& f) {
  646.     OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
  647.   }
  648.  
  649. public:
  650.   Alpha_Field(int width)
  651.     : NCursesFieldType(TYPE_ALPHA),
  652.       min_field_width(width) {
  653.   }
  654. };
  655.  
  656. class NCURSES_IMPEXP Alphanumeric_Field : public NCursesFieldType {
  657. private:
  658.   int min_field_width;
  659.  
  660.   void set(NCursesFormField& f) {
  661.     OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
  662.   }
  663.  
  664. public:
  665.   Alphanumeric_Field(int width)
  666.     : NCursesFieldType(TYPE_ALNUM),
  667.       min_field_width(width) {
  668.   }
  669. };
  670.  
  671. class NCURSES_IMPEXP Integer_Field : public NCursesFieldType {
  672. private:
  673.   int precision;
  674.   long lower_limit, upper_limit;
  675.  
  676.   void set(NCursesFormField& f) {
  677.     OnError(::set_field_type(f.get_field(),fieldtype,
  678.                  precision,lower_limit,upper_limit));
  679.   }
  680.  
  681. public:
  682.   Integer_Field(int prec, long low=0L, long high=0L)
  683.     : NCursesFieldType(TYPE_INTEGER),
  684.       precision(prec), lower_limit(low), upper_limit(high) {
  685.   }
  686. };
  687.  
  688. class NCURSES_IMPEXP Numeric_Field : public NCursesFieldType {
  689. private:
  690.   int precision;
  691.   double lower_limit, upper_limit;
  692.  
  693.   void set(NCursesFormField& f) {
  694.     OnError(::set_field_type(f.get_field(),fieldtype,
  695.                  precision,lower_limit,upper_limit));
  696.   }
  697.  
  698. public:
  699.   Numeric_Field(int prec, double low=0.0, double high=0.0)
  700.     : NCursesFieldType(TYPE_NUMERIC),
  701.       precision(prec), lower_limit(low), upper_limit(high) {
  702.   }
  703. };
  704.  
  705. class NCURSES_IMPEXP Regular_Expression_Field : public NCursesFieldType {
  706. private:
  707.   char* regex;
  708.  
  709.   void set(NCursesFormField& f) {
  710.     OnError(::set_field_type(f.get_field(),fieldtype,regex));
  711.   }
  712.  
  713. public:
  714.   Regular_Expression_Field(const char *expr)
  715.     : NCursesFieldType(TYPE_REGEXP) {
  716.       regex = new char[1 + ::strlen(expr)];
  717.       (::strcpy)(regex,expr);
  718.   }
  719.  
  720.   ~Regular_Expression_Field() {
  721.     delete[] regex;
  722.   }
  723. };
  724.  
  725. class NCURSES_IMPEXP Enumeration_Field : public NCursesFieldType {
  726. private:
  727.   char** list;
  728.   int case_sensitive;
  729.   int non_unique_matches;
  730.  
  731.   void set(NCursesFormField& f) {
  732.     OnError(::set_field_type(f.get_field(),fieldtype,
  733.                  list,case_sensitive,non_unique_matches));
  734.   }
  735. public:
  736.   Enumeration_Field(char* enums[],
  737.             bool case_sens=FALSE,
  738.             bool non_unique=FALSE)
  739.     : NCursesFieldType(TYPE_ENUM),
  740.       list(enums),
  741.       case_sensitive(case_sens?-1:0),
  742.       non_unique_matches(non_unique?-1:0) {
  743.   }
  744. };
  745.  
  746. class NCURSES_IMPEXP IPV4_Address_Field : public NCursesFieldType {
  747. private:
  748.   void set(NCursesFormField& f) {
  749.     OnError(::set_field_type(f.get_field(),fieldtype));
  750.   }
  751.  
  752. public:
  753.   IPV4_Address_Field() : NCursesFieldType(TYPE_IPV4) {
  754.   }
  755. };
  756. //
  757. // -------------------------------------------------------------------------
  758. // Abstract base class for User-Defined Fieldtypes
  759. // -------------------------------------------------------------------------
  760. //
  761. class NCURSES_IMPEXP UserDefinedFieldType : public NCursesFieldType {
  762.   friend class UDF_Init; // Internal helper to set up statics
  763. private:
  764.   // For all C++ defined fieldtypes we need only one generic lowlevel
  765.   // FIELDTYPE* element.
  766.   static FIELDTYPE* generic_fieldtype;
  767.  
  768. protected:
  769.   // This are the functions required by the low level libforms functions
  770.   // to construct a fieldtype.
  771.   static bool fcheck(FIELD *, const void*);
  772.   static bool ccheck(int c, const void *);
  773.   static void* makearg(va_list*);
  774.  
  775.   void set(NCursesFormField& f) {
  776.     OnError(::set_field_type(f.get_field(),fieldtype,&f));
  777.   }
  778.  
  779. protected:
  780.   // Redefine this function to do a field validation. The argument
  781.   // is a reference to the field you should validate.
  782.   virtual bool field_check(NCursesFormField& f) = 0;
  783.  
  784.   // Redefine this function to do a character validation. The argument
  785.   // is the character to be validated.
  786.   virtual bool char_check (int c) = 0;
  787.  
  788. public:
  789.   UserDefinedFieldType() : NCursesFieldType(generic_fieldtype) {
  790.   }
  791. };
  792. //
  793. // -------------------------------------------------------------------------
  794. // Abstract base class for User-Defined Fieldtypes with Choice functions
  795. // -------------------------------------------------------------------------
  796. //
  797. class NCURSES_IMPEXP UserDefinedFieldType_With_Choice : public UserDefinedFieldType {
  798.   friend class UDF_Init; // Internal helper to set up statics
  799. private:
  800.   // For all C++ defined fieldtypes with choice functions we need only one
  801.   // generic lowlevel FIELDTYPE* element.
  802.   static FIELDTYPE* generic_fieldtype_with_choice;
  803.  
  804.   // This are the functions required by the low level libforms functions
  805.   // to construct a fieldtype with choice functions.
  806.   static bool next_choice(FIELD*, const void *);
  807.   static bool prev_choice(FIELD*, const void *);
  808.  
  809. protected:
  810.   // Redefine this function to do the retrieval of the next choice value.
  811.   // The argument is a reference to the field tobe examined.
  812.   virtual bool next    (NCursesFormField& f) = 0;
  813.  
  814.   // Redefine this function to do the retrieval of the previous choice value.
  815.   // The argument is a reference to the field tobe examined.
  816.   virtual bool previous(NCursesFormField& f) = 0;
  817.  
  818. public:
  819.   UserDefinedFieldType_With_Choice() {
  820.     fieldtype = generic_fieldtype_with_choice;
  821.   }
  822. };
  823.  
  824. #endif // NCURSES_CURSESF_H_incl
  825.  
  826.